Create a JwtStrategy that validates the Bearer token from the Authorization header using the access token secret. In AuthService, sign separate access (short-lived) and refresh (long-lived) tokens with different secrets. Store a hashed refresh token in the database and verify it on the refresh endpoint.
Access tokens should be short-lived (15 minutes) — limits the window if a token is stolen.
Refresh tokens should be long-lived (7 days) but stored hashed in the database.
Use separate secrets for access and refresh tokens — a compromised refresh secret does not affect access verification.
Never store plain refresh tokens — always hash with bcrypt before saving to the database.
Validate refresh tokens by comparing the incoming token against the hashed version in the database.